#pragma once

#include "../bm/def.h"

void (*video_printf)(const char *fmt, ...) = (void (*)(const char *fmt, ...))(0x4602CDF0 | 1);
part_dev_t *(*mt_part_get_device)() = (part_dev_t * (*)())(0x4601AB58 | 1);
part_t *(*mt_part_get_partition)(const char *name) = (part_t * (*)(const char *name))(0x460045DC | 1);
void (*arch_clean_invalidate_cache_range)(uint32_t start, uint32_t size) = (void (*)(uint32_t, uint32_t))0x4601AE00;

typedef struct udc_device {
	uint16_t vendor_id;
	uint16_t product_id;
	uint16_t version_id;

	const char *manufacturer;
	const char *product;
	const char *serialno;
} udc_device_t;

struct udc_endpoint;

#define UDC_EVENT_ONLINE        1
#define UDC_EVENT_OFFLINE       2

typedef struct udc_gadget udc_gadget_t;
struct udc_gadget {
        void (*notify)(udc_gadget_t *gadget, unsigned event);
        void *context;

        unsigned char ifc_class;
        unsigned char ifc_subclass;
        unsigned char ifc_protocol;
        unsigned char ifc_endpoints;
        const char *ifc_string;
        unsigned flags;

        struct udc_endpoint **ept;
};

int (*udc_init)(udc_device_t*dev) = (int(*)(udc_device_t*))(0x4600E5DC | 1);
int (*udc_register_gadget)(udc_gadget_t* g) = (int(*)(udc_gadget_t*))(0x4600E76C | 1);
int (*udc_start)(void) = (int(*)(void))(0x4600E790 | 1);

#define UDC_TYPE_BULK_IN        1
#define UDC_TYPE_BULK_OUT       2

struct udc_endpoint *(*udc_endpoint_alloc)(unsigned type, unsigned maxpkt) = (struct udc_endpoint*(*)(unsigned,unsigned))(0x4600DC28 | 1);

typedef struct udc_request udc_request_t;
struct udc_request {
        void *buf;
        unsigned length;
        void (*complete)(udc_request_t *req, unsigned actual, int status);
        void *context;
};

//udc_request_t *udc_request_alloc(void);

int (*udc_request_queue)(struct udc_endpoint*ept, struct udc_request*req) = (int(*)(struct udc_endpoint*,struct udc_request*))(0x4600E678 | 1);
